package com.kai.aspect;

import com.kai.anno.AutoFill;
import com.kai.enumeration.AutoFillEnum;
import com.kai.threadlocal.BaseContest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.Advisor;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Configuration
@Slf4j
public class AutoFillAspect {

    @Value("${pointcuts.autofill}")
    private String autofillPackage;


    @Bean
    //定义为基础设施bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public Advisor autoFillAdvisor() {
        //创建切入点
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();


        // 动态拼接切入点表达式
        String expression = "execution(* " + autofillPackage + ".*.*(..)) && @annotation(com.kai.anno.AutoFill)";
        pointcut.setExpression(expression);


        MethodBeforeAdvice advice = (method, args, target) -> {


            // 通过method获得方法的注解
            AutoFill annotation = method.getAnnotation(com.kai.anno.AutoFill.class);
            AutoFillEnum value = annotation.value();
            // 方法参数 默认第一位为实体对象
            Object entity = args[0];
            LocalDateTime now = LocalDateTime.now();
            Long userId = BaseContest.getCurrentId();
            try {
                if (value == AutoFillEnum.INSERT) {
                    log.info("插入数据 公共字段填充");
                    Method setCreateTime = entity.getClass().getDeclaredMethod(com.kai.constant.AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                    Method setUpdateTime = entity.getClass().getDeclaredMethod(com.kai.constant.AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                    setCreateTime.invoke(entity, now);
                    setUpdateTime.invoke(entity, now);
                } else {
                    log.info("更新数据 公共字段填充");
                    Method setUpdateTime = entity.getClass().getDeclaredMethod(com.kai.constant.AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                    setUpdateTime.invoke(entity, now);
                }
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }


        };

        //创建 Advisor（切入点 + 增强逻辑）
        return new DefaultPointcutAdvisor(pointcut, advice);
    }



//  ------------------------弃用
// @Slf4j
//@Component
//@Aspect
//public class AutoFillAspect1 {
//
//
//
//    @Pointcut("@annotation(com.kai.anno.AutoFill)")
//    public void autoFillPointCut() {
//    }
//
//    @Before("autoFillPointCut()")
//    public void autoFill(JoinPoint joinPoint) {
//
//        log.info("开始进行公共数据填充");
//        //通过joinPoint获得方法签名
//        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//        //通过方法签名获得方法的注解
//        AutoFill annotation = signature.getMethod().getAnnotation(AutoFill.class);
//        //获得注解的类型
//        AutoFillEnum value = annotation.value();
//
//        //通过joinPoint获得方法参数 默认第一位为实体对象
//        Object entity = joinPoint.getArgs()[0];
//
//        //当前时间
//        LocalDateTime now = LocalDateTime.now();
//
//
//        //
//        try {
//
//            if (value == AutoFillEnum.INSERT) {
//                //反射获取方法
//                Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
//                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
//                //执行
//                setCreateTime.invoke(entity, now);
//                setUpdateTime.invoke(entity, now);
//            } else {
//                //更新的公共字段填充
//                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
//                setUpdateTime.invoke(entity, now);
//            }
//
//        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
//            throw new RuntimeException(e);
//        }
//    }
//
//}





}